package com.example.demo1.utils;

import java.io.IOException;
import java.sql.*;
import java.util.*;

/**
 * 通过单例模式创建JDBCUtils实例
 */
public class JdbcUtils {
    //存放实例
    static ThreadLocal<JdbcUtils> threadLocal = new ThreadLocal<>();

    private String url;
    private String user;
    private String password;

    /**
     * 构造方法设置成私有，不允许外部直接实例化
     */
    private JdbcUtils() {
        Properties prop = new Properties();
        try {
            prop.load(JdbcUtils.class.getResourceAsStream("/jdbc.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Object driverObj = prop.get("jdbc.driver");
        Object urlObj = prop.get("jdbc.url");
        Object userObj = prop.get("jdbc.username");
        Object passwordObj = prop.get("jdbc.password");

        if (!StringUtil.isEmpty(driverObj)) {
            System.out.println("driver不能是空的");
        } else if (!StringUtil.isEmpty(urlObj)) {
            System.out.println("url不能是空的");
        } else if (!StringUtil.isEmpty(userObj)) {
            System.out.println("user不能是空的");
        } else if (!StringUtil.isEmpty(passwordObj)) {
            System.out.println("password不能是空的");
        } else {
            try {
                url = urlObj.toString();
                user = userObj.toString();
                password = passwordObj.toString();
                //加载驱动
                Class.forName(driverObj.toString());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 更改：增加、修改
     * sql中的字段与参数的位置和数量对应
     */
    public Integer saveData(Connection conn, String sql, Object... objs) {
        PreparedStatement ps;
        int i = 1;
        try {
            ps = conn.prepareStatement(sql);
            for (Object obj : objs) {
                ps.setObject(i++, obj);
            }
            ps.execute();
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new InputMismatchException("参数不匹配");
        }
    }

    /**
     * 查询
     */
    public List<Map<String, Object>> getDataList(Connection conn, String sql, Object... params) {
        PreparedStatement ps = null;
        List<Map<String, Object>> resultList = new ArrayList<>();
        int i = 1;

        try {
            ps = conn.prepareStatement(sql);
            if (null != params || 0 == params.length) {
                for (Object obj : params) {
                    ps.setObject(i++, obj);
                }
            }
            ResultSet rs = ps.executeQuery();
            //获取结果集中列字段的信息
            ResultSetMetaData md = rs.getMetaData();
            //处理结果集的每一行
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                //处理某行每一列数据
                for (int colNum = 1; colNum <= md.getColumnCount(); colNum++) {
                    map.put(md.getColumnName(colNum), rs.getObject(colNum));
                }
                resultList.add(map);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return resultList;
    }

    /**
     * 获取当前类的实例
     */
    public static JdbcUtils getInstance() {
        JdbcUtils jdbcUtil = threadLocal.get();
        if (null == jdbcUtil) {
            jdbcUtil = new JdbcUtils();
            threadLocal.set(jdbcUtil);
        }

        return jdbcUtil;
    }

    /**
     * 获取连接
     */
    public Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return conn;
    }

    /**
     * 关闭连接
     */
    public void closeConn(Connection conn) {
        if (null == conn) {
            return;
        }

        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭语句
     */
    public void closeStmt(Statement stmt) {
        if (null == stmt) {
            return;
        }

        try {
            stmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭ResultSet
     */
    public void closeRs(ResultSet rs) {
        if (null == rs) {
            return;
        }

        try {
            rs.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 关闭所有资源
     */
    public void closeAll(Connection conn, Statement stmt, ResultSet rs) {
        this.closeConn(conn);
        this.closeStmt(stmt);
        this.closeRs(rs);
    }
}
